package cn.com.zonesion.rfiddemo.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.x210.android.serialPortSample.SerialPort;
import com.x210.android.serialPortSample.SerialPortFinder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

import butterknife.BindView;
import butterknife.ButterKnife;
import cn.com.zonesion.rfidV2.Cardutil;
import cn.com.zonesion.rfiddemo.R;
import cn.com.zonesion.rfiddemo.adapter.InstructionListAdapter;
import cn.com.zonesion.rfiddemo.base.BaseFragment;
import cn.com.zonesion.rfiddemo.bean.InstructionBean;
import cn.com.zonesion.rfiddemo.fragment.BasicsFragmet;


public class IdMainActivity extends FragmentActivity implements View.OnTouchListener{
    /**
     * 该视图用来替换成要切换的页面
     */
    @BindView(R.id.content_fragment)
    FrameLayout contentFragment;

    @BindView(R.id.btn_slide_data)
    Button btnSlideData;
    /**
     * 该按钮用来连接和断开串口
     */
    @BindView(R.id.btn_connection)
    Button btnConnection;

    /**
     * 该ListView用来展示发送的指令以及指令的作用
     */
    @BindView(R.id.listView_debugging)
    ListView listViewDebugging;
    @BindView(R.id.rg_bottom_tag_id)
    RadioGroup rgBottomTag;
    /**
     * 标识是否串口链接成功
     */
    @BindView(R.id.image_link_icon)
    ImageView imageLinkIcon;
    /**
     * 展示当前系统时间
     */
    @BindView(R.id.tv_current_time)
    TextView tvCurrentTime;
    /**
     * 标识是否向用户提示串口是否连接成功
     */
    private boolean hasTipConnection = false;

    /**
     * 是否启动了读取数据的线程
     */
    private boolean hasStartThread;
    /**
     * 该线程用来读取数据
     */
    private Thread readThread;
    /**
     * 用来存放InstructionBean对象的ArrayList
     */
    private ArrayList<InstructionBean> instructionBeanArrayList;
    /**
     * 存放串口名称
     */
    private List<String> driverList;
    /**
     * 波特率数组，用来存放常用波特率
     */
    private String[] baudrateArray;

    /**
     * ListView的适配器对象
     */
    private InstructionListAdapter adapter;
    /**
     * 串口对象
     */
    private SerialPort serialPort;

    /**
     * 串口路径
     */
    private File serialPath;
    /**
     * 串口对应的波特率
     */
    private int baudrate;
    /**
     * AttendanceHandler主要用来做一些定时的工作
     */
    private AttendanceHandler handler;
    /**
     * AttendanceHandler发送消息定时获取系统时间的标识
     */
    private static final int GET_SYSTEM_TIME = 0;
    /**
     * AttendanceHandler发送消息定时查询卡号的标识
     */
    private static final int QUERY_CARD_NUM = 1;
    /**
     * AttendanceHandler发送消息定时检测获取串口的标识符
     */
    private static final int CHECK_SERIAlPORT = 2;
    /**
     * 用来标识串口是否连接成功
     */
    private boolean serialConnectSus = false;

//    public static final String SERIAL_LINK = "串口连接";


    /**
     * 装多个Fragment的实例集合
     */
    private ArrayList<BaseFragment> fragments;
    private int position = 0;
    /**
     * 缓存的Fragemnt或者上次显示的Fragment
     */
    private Fragment tempFragemnt;

    private static final int msgKey1 = 1;

//    private Handler mHandler = new Handler() {
//        @Override
//        public void handleMessage (Message msg) {
//            super.handleMessage(msg);
//            switch (msg.what) {
//                case msgKey1:
//                    tvCurrentTime.setText(getTime());
//                    break;
//                default:
//                    break;
//            }
//        }
//    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_id);
        ButterKnife.bind(this);//将ButterKnife和MainActivity绑定
        /**
         * 初始化Fragment
         */
        initFragment();
        //设置RadioGroup的监听
        initListener();

        initView();

        handler.sendEmptyMessage(CHECK_SERIAlPORT);//发送消息检测串口
    }
    private void initListener(){
        rgBottomTag.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case  R.id.btn_basics_id://基础
                        position = 0;
                        break;
                    default:
                        position = 0;
                        break;

                }
                //根据位置取不同的Fragment
                BaseFragment baseFragment = getFragment(position);
                switchFragment(tempFragemnt, baseFragment);
            }
        });
        rgBottomTag.check(R.id.btn_basics_id);
    }
    /**
     * 添加的时候要按照顺序
     */
    private void initFragment() {
        fragments = new ArrayList<>();
        fragments.add(new BasicsFragmet());

    }

    private BaseFragment getFragment(int position) {
        if (fragments != null && fragments.size() > 0) {
            BaseFragment baseFragment = fragments.get(position);
            return baseFragment;
        }
        return null;
    }
    private void switchFragment(Fragment fromFragment, BaseFragment nextFragment) {
        if (tempFragemnt != nextFragment) {
            tempFragemnt = nextFragment;
            if (nextFragment != null) {
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                //判断nextFragment是否添加
                if (!nextFragment.isAdded()) {
                    //隐藏当前Fragment
                    if (fromFragment != null) {
                        transaction.hide(fromFragment);
                    }
                    //添加Fragment
                    transaction.add(R.id.content_fragment, nextFragment).commit();
                } else {
                    //隐藏当前Fragment
                    if (fromFragment != null) {
                        transaction.hide(fromFragment);
                    }
                    transaction.show(nextFragment).commit();
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        //在Activity销毁之前，移除所有的消息和回调
        handler.removeCallbacksAndMessages(null);
        if(serialPort != null) {
            serialPort.close();//如果serialPort不是null，当activity销毁的时候，关闭串口连接
        }
        super.onDestroy();
    }

//    /**
//     * 该方法负责控件的初始化，为自定义的方法。在该方法中负责获取FragmentManager对象，初始化两个页面，
//     * BasicsFragmet设置按钮被选中时和没被选中时的背景颜色
//     */
    private void initView(){

//        new TimeThread().start();
        instructionBeanArrayList = new ArrayList<>();
        adapter = new InstructionListAdapter(this,instructionBeanArrayList);//构造一个适配器对象
        listViewDebugging.setAdapter(adapter);//为ListView设置适配器
        baudrateArray = getResources().getStringArray(R.array.baudrate);
        driverList = new ArrayList<>();
//        //初始化handler
        handler = new AttendanceHandler(this);

        //为btnConnection注册单击事件
        btnConnection.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                /**
                 * 首先得到按钮上的文本 如果是"连接串口" 则点击 该按钮连接串口 并将按钮上的文本改为"关闭串口"
                 * 并开启读取数据的线程 发送消息查询卡号
                 */
                if(btnConnection.getText().toString().equals("连接串口")) {
                    showOpenTheSerialPort("串口设置");
                    /**
                     * 如果按钮文本为"关闭串口" 点击之后 则将文本置为"连接串口" 并将界面上的文本框所有数据以及全局变量恢复为初始值
                     * 调用串口的close()方法关闭串口
                     */
                }else if(btnConnection.getText().toString().equals("关闭串口")){
                    btnConnection.setText("连接串口");
                    imageLinkIcon.setBackgroundResource(R.drawable.to_break_off);
                    hasStartThread = false;
                    serialConnectSus = false;
                    Thread t = new Thread(){
                        public void run(){
                            if (serialPort != null) {
                                hasStartThread = false;
                                if (readThread != null) {

                                    try {
                                        readThread.join();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
//                                   readThread = null;
                                }
                                serialPort.close();
//                               serialPort = null;

                            }
                        }
                    };
                    readThread = null;
                    serialPort = null;
                    t.start();
                }
            }
        });
//        //为btnSlideData注册点击事件
//        btnSlideData.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                if(btnSlideData.getText().toString().equals("停止滑动数据")){
//                    btnSlideData.setText("开启滑动数据");
//                } else if(btnSlideData.getText().toString().equals("开启滑动数据")){
//                    btnSlideData.setText("停止滑动数据");
//                }
//            }
//        });
    }
//    public class TimeThread extends Thread {
//        @Override
//        public void run () {
//            do {
//                try {
//                    Thread.sleep(1000);
//                    Message msg = new Message();
//                    msg.what = msgKey1;
//                    mHandler.sendMessage(msg);
//                }
//                catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            } while(true);
//        }
//    }

    /**
     * /获得当前年月日时分秒星期
     * @return
     */
    public String getTime(){
        final Calendar c = Calendar.getInstance();
        c.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        String mYear = String.valueOf(c.get(Calendar.YEAR)); // 获取当前年份
        String mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 获取当前月份
        String mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 获取当前月份的日期号码
        String mWay = String.valueOf(c.get(Calendar.DAY_OF_WEEK));
        String mHour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));//时
        String mMinute = String.valueOf(c.get(Calendar.MINUTE));//分
        String mSecond = String.valueOf(c.get(Calendar.SECOND));//秒
        if("1".equals(mWay)){
            mWay ="天";
        }else if("2".equals(mWay)){
            mWay ="一";
        }else if("3".equals(mWay)){
            mWay ="二";
        }else if("4".equals(mWay)){
            mWay ="三";
        }else if("5".equals(mWay)){
            mWay ="四";
        }else if("6".equals(mWay)){
            mWay ="五";
        }else if("7".equals(mWay)){
            mWay ="六";
        }
        return mYear + "年" + mMonth + "月" + mDay+"日"+" "+"星期"+mWay+" "+mHour+":"+mMinute+":"+mSecond;
    }



    private void showOpenTheSerialPort(String title){
        View view = View.inflate(IdMainActivity.this,R.layout.activity_seria_iport_picker,null);
        //找到布局文件中的控件
        final Spinner ttySpinner = view.findViewById(R.id.tty_spinner);
        final Spinner ttyBaudrate = view.findViewById(R.id.tty_baudrate);
        ttySpinner.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,driverList));
        ttyBaudrate.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,baudrateArray));
        /*
         * 开启一个线程来获取当前可用的串口路径
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                String[] driverVector = new SerialPortFinder().getAllDevicesPath();//该方法用来获取可用的串口路径
                driverList.clear();
                driverList.addAll(Arrays.asList(driverVector));//将获取到的串口路径已字符串的形式添加进driverList里
            }
        }).start();
        //为ttySpinner设置适配器
        ttySpinner.setAdapter(new ArrayAdapter<>(getApplicationContext(),R.layout.spinner_layout,R.id.textView,driverList));
        //为ttySpinner注册监听事件
        ttySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                serialPath = new File(driverList.get(position));
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });
        //为ttyBaudrate注册监听事件
        ttyBaudrate.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
                baudrate = Integer.parseInt(baudrateArray[position]);
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {}
        });
       new AlertDialog.Builder(this)
                   .setTitle(title)//给AlertDialog设置对应的标题
                   .setView(view)//给AlertDialog设置对应的布局
                   .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                       @Override
                       public void onClick(DialogInterface dialog, int which) {
                           hasTipConnection = false;
                           if (serialPort == null) {
                               try {
                                   serialPort = new SerialPort(serialPath, baudrate);
                                   btnConnection.setText("关闭串口");
                                   imageLinkIcon.setBackgroundResource(R.drawable.link);
                                   //是否启动读取线程boolean
                                   if(!hasStartThread) {
                                       //该线程用来读取数据Thread
                                       if (readThread == null) {
                                           //启动线程
                                           hasStartThread = true;
                                           readThread = new Thread(new ReadThread());
                                           readThread.start();//开启读取数据的线程
                                       }
                                   }
                                   handler.sendEmptyMessage(QUERY_CARD_NUM);//发送消息查询125K卡号
                               } catch (IOException | SecurityException e) {
                                   /**
                                    * 串口对象创建出现异常 则提示用户 并将文本重新设为"连接串口"
                                    * 将serialPort和hasStartThread置为原始值 以便能够重新连接串口
                                    */
                                   e.printStackTrace();
                                   Toast.makeText(getApplicationContext(), "串口对象创建异常，请检查串口或波特率是否正确,并重新连接", Toast.LENGTH_SHORT).show();
                                   btnConnection.setText("连接串口");
                                   imageLinkIcon.setBackgroundResource(R.drawable.to_break_off);
                                   serialPort = null;
                                   hasStartThread = false;
                               }

                           }
                           btnConnection.setText("关闭串口");
                       }
                   })
                   .setNegativeButton("取消", null)
                   .show();
    }
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }

    //该线程负责读取串口发来的数据
    private class ReadThread implements Runnable{

        @Override
        public void run() {
            String str;
            //获取串口的输出流，以便于串口数据的收发
            InputStream inputStream = serialPort.getInputStream();
            final byte[] receive = new byte[25];
            try {
                int ret = 0, offset = 0;
                while (hasStartThread && (ret = inputStream.read(receive, offset, 25 - offset)) != -1) {
                    offset += ret;
                    Log.e("获取的16进制数字", Cardutil.outByteArray(receive));
                    if ((receive[0] & 0xff) == 0xCD && (receive[1] & 0xff) == 0xDC) {
                        serialConnectSus = true;
                        final int finalOffset = offset;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if(!hasTipConnection) {
                                    //串口有数据返回的时候 提示用户"串口连接成功"
                                    Toast.makeText(getApplicationContext(), "串口连接成功", Toast.LENGTH_SHORT).show();
                                    hasTipConnection = true;
                                }
                            }
                        });
                    } else {
                        offset = 0;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                hasStartThread = false;
            }
        }
    }

    //该方法用于发生查询卡的指令
    private void dataDeal() {
        if (serialPort != null) {
            OutputStream outputStream = serialPort.getOutputStream();
            try {
                byte[] dat = new byte[]{(byte) 0xab, (byte) 0xba, 0x00, 0x15, 0x00, 0x15};
                outputStream.write(dat);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * bytes转换成十六进制字符串
     * @param b byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byte2HexStr(byte[] b)
    {
        String stmp="";
        StringBuilder sb = new StringBuilder("");
        for (int n=0;n<b.length;n++)
        {
            stmp = Integer.toHexString(b[n] & 0xFF);
            sb.append((stmp.length()==1)? "0"+stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }

    static class AttendanceHandler extends Handler {
        //创建弱引用，防止内存泄露
        private WeakReference<IdMainActivity> reference;

        AttendanceHandler(IdMainActivity mainActivity){
            //在构造方法中对reference初始化
            reference = new WeakReference<>(mainActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case IdMainActivity.GET_SYSTEM_TIME:
                    if(reference.get() != null) {
                    }
                    break;
                case IdMainActivity.CHECK_SERIAlPORT:
                    if(reference.get()!=null) {
                        String[] driverVector = new SerialPortFinder().getAllDevicesPath();
                        reference.get().driverList.clear();
                        reference.get().driverList.add("请选择串口：");
                        reference.get().driverList.addAll(Arrays.asList(driverVector));
                    }
//                    removeMessages(IdMainActivity.CHECK_SERIAlPORT);
                    break;
                case IdMainActivity.QUERY_CARD_NUM:
                    if(reference.get()!=null) {
                        //查询125K
                        reference.get().dataDeal();
                        //串口对象不等于空
                        if(reference.get().serialPort != null) {
                            //用来标识串口是否连接成功
                            if(reference.get().serialConnectSus) {

                            }
                        }
                    }
                    removeMessages(IdMainActivity.QUERY_CARD_NUM);
                    break;
            }
        }
    }
}
